-- ScoutM
-- created by panyl
-- 斥候探索

module("ScoutM", package.seeall);

local exploreConfig = {};

-- 玩家当前探索的数据
local exploreData = {};
local bonusStat   = {}; -- 奖励累计
local startTimeRecord;  -- 本次发起探索时间

-- 载入配置表
local _init = false;
local loadCsv = function()
    if _init then return end
    _init = true;

    -- 清空
    exploreConfig = {};

    -- 转换下scout_explore信息表
    local scout_explore_CSV = get_scout_explore_CSV();
    for i = 1, #scout_explore_CSV do
        local grade = scout_explore_CSV[i].grade
        exploreConfig[grade] = scout_explore_CSV[i];
    end
end

-- 模块初始化操作
function init()
    -- 清空所有数据
    clearData();

    loadCsv();
end

-- 清空所有数据
function clearData()
    exploreData = {};
    bonusStat   = {}; 
    startTimeRecord = nil;
end

-- 检索
function query(grade, path)
    local m = exploreConfig[grade];
    if not m or not path then
        return m;
    end

    return m[path];
end

-- 查询当前探索数据
function queryExplore(path)
    if path then
        return exploreData[path];
    end

    return exploreData;
end

-- 查询原始奖励数据
function queryOriBonus()
    return bonusStat;
end

-- 查询当前奖励池
function queryBonus()
    return bonusStat;
end

-- 当前斥候数量
function getScoutCount()
    return ME.user.dbase:query("scout", 0);
end

-- 最大探索时间
function calcMaxExploreTime()
    -- 公式计算
    return FormulaM.invoke("CALC_MAX_SCOUT_EXPLORE_TIME", ME.user);
end

-- 获得开始时间
function getStartTime()
    return exploreData["start_time"];
end

-- 剩余探索时间
function getLeftTime()
    if not isExploring() then
        -- 不在探索状态中
        return 0;
    end

    -- 开始时间/服务器时间
    local startTime;
    if not startTimeRecord then
        startTime = exploreData["start_time"];
    else
        startTime = startTimeRecord;
    end

    local currTime  = TimeM.getServerTime();

    -- 已经探索时间
    local exploreTime = currTime - startTime;

    -- 剩余时间
    local leftTime = calcMaxExploreTime() - exploreTime;

    -- 由于延迟，故增加个5s
    return math.min(leftTime + 5, calcMaxExploreTime());
end

-- 是否探索中
function isExploring()
    -- 只要数据不空就是探索中
    return exploreData["start_time"] ~= nil;
end

-- 去服务器获取一下最新的探索数据
function refreshExploreData()
    -- 如果没在探索中
    if not isExploring() then
        return;
    end

    -- 下一档位的奖励
    local nextGrade = exploreData["last_grade"] + 1;
    if not query(nextGrade) then
        -- 没有下一档位
        return;
    end

    -- 服务器时间
    local currTime  = TimeM.getServerTime();

    local startTime;
    if not startTimeRecord then
        startTime = exploreData["start_time"];
    else
        startTime = startTimeRecord;
    end

    local lastTime  = math.min(calcMaxExploreTime(), currTime - startTime);

    -- 如果还未达到下档位时间,富余5s
    if lastTime < query(nextGrade, "time") - 5 then
        return;
    end

    -- 直接发起请求
    Operation.cmd_refresh_explore_data();
end

-- 更新探索数据
function updateExploreData(data, bonus)
    exploreData = data;

    if isExploring() then
        bonusStat   = table.add(bonusStat, bonus);
    else
        bonusStat = {};
    end
    
    if not startTimeRecord then
        -- 设置本次探索开始时间
        startTimeRecord = exploreData["start_time"];
    end

    -- 抛出事件
    EventMgr.fire(event.SCOUT_INFO_UPDATE);
    
    -- 抛出事件用于更新主地图提示
    EventMgr.fire(event.WORKSHOP_INFO_UPDATED);
end

function updateExploreBonus(bonus)
    bonusStat = bonus;

    -- 抛出事件
    EventMgr.fire(event.SCOUT_INFO_UPDATE);
end

-- 判断能否探索
function canStartExplore()
    -- 如果正在探索中
    if isExploring() then
        return false;
    end

    -- 如果没有斥候
    if getScoutCount() <= 0 then
        return false;
    end

    return true;
end

-- 开始探索
function startExplore()
    if not canStartExplore() then
        return false;
    end

    -- 清空上次的数据
    exploreData = {};
    bonusStat = {};
    startTimeRecord = nil;

    -- 直接发起
    Operation.cmd_star_scout_explore();

    return true;
end

-- 结束探索
function stopExplore()
    -- 是否探索中
    if not isExploring() then
        return false;
    end

    -- 先做奖励
    for _, bonus in pairs(bonusStat) do
        local classId = bonus["class_id"];
        local amount  = bonus["count"] * bonus["times"];
        local prop;
        
        if type(classId) == "string" then
            -- 加成
            prop = PropM.combine(ME.user, "scout_bonus", classId);
            amount =  PropM.apply(prop, amount);
            
            -- 加属性
            ME.user:addAttrib(classId, amount);
        elseif type(classId) == "number" then
            -- 加成，只管食材
            if ItemM.isFoodMaterial(classId) then
                prop = PropM.combine(ME.user, "scout_bonus", "food_material");
                amount = PropM.apply(prop, amount);
            end

            -- 加物品
            ItemM.addAmount(ME.user, classId, amount, { ["desc"] = "explore_bonus" });
        else
            assert(0);
        end
    end

    -- 客户端奖励完了清空所有相关数据
    exploreData = {};
    bonusStat = {};
    startTimeRecord = nil;

    -- 直接发起
    Operation.cmd_stop_scout_explore();

    return true;
end
